package com.vivz.baby.config;

import java.util.Properties;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.springframework.core.env.Environment;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;

import com.google.common.base.Preconditions;

public abstract class PersistenceJPAConfig {
	
	protected abstract Environment getEnvironment();
	
	protected DataSource dataSource() {
		final DriverManagerDataSource dataSource = new DriverManagerDataSource();
		final Environment environment = getEnvironment();
		dataSource.setDriverClassName(Preconditions.checkNotNull(environment.getProperty("jdbc.driverClassName")));
		dataSource.setUrl(Preconditions.checkNotNull(environment.getProperty("jdbc.url")));
		dataSource.setUsername(Preconditions.checkNotNull(environment.getProperty("jdbc.user")));
		dataSource.setPassword(Preconditions.checkNotNull(environment.getProperty("jdbc.pass")));
		
		System.out.println("------> jdbc.url: \t" + environment.getProperty("jdbc.url"));
		return dataSource;
	}
	
	protected LocalContainerEntityManagerFactoryBean entityManagerFactory() {
		final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
		em.setDataSource(dataSource());
		em.setPackagesToScan(new String[] { "com.vivz.baby" });
		
		final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
		em.setJpaVendorAdapter(vendorAdapter);
		em.setJpaProperties(additionalProperties());
		
		return em;
	}
	
	protected PlatformTransactionManager transactionManager(final EntityManagerFactory emf) {
		final JpaTransactionManager transactionManager = new JpaTransactionManager();
		transactionManager.setEntityManagerFactory(emf);
		return transactionManager;
	}
	
	protected PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
		return new PersistenceExceptionTranslationPostProcessor();
	}
	
	private final Properties additionalProperties() {
		final Properties hibernateProperties = new Properties();
		final Environment environment = getEnvironment();
		hibernateProperties.setProperty("hibernate.hbm2ddl.auto", environment.getProperty("hibernate.hbm2ddl.auto"));
		hibernateProperties.setProperty("hibernate.dialect", environment.getProperty("hibernate.dialect"));
		return hibernateProperties;
	}
}
